package com.wis.application;

import android.app.Application;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Environment;
import android.telephony.TelephonyManager;
import android.util.Base64;
import android.util.Log;

//import com.umeng.analytics.MobclickAgent;
//import com.wis.face.WisMobile;

import com.wis.face.FileUtils;
import com.wis.face.HttpDownloader;
import com.wis.face.WisUtil;

import java.io.File;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import face.com.androidfacesdk.FaceMobile;

import face.comparer.Face2FaceHelper;
import face.detector.FaceDetection;
import face.detector.FacePointsDetection;
import face.entity.FaceFeaturePoint;
import face.entity.FaceModel;

/**
 * Created by ybbz on 16/9/1.
 */
public class WisApplication extends Application {

    private static final String TAG = "WisApplication";

    private static final int ASSETS_SUFFIX_BEGIN = 0;
    private static final int ASSETS_SUFFIX_END = 9;

    //private 特征检测对象;
    private FaceMobile wisMobile;
    //人脸检测对象
    private FaceDetection faceDetection;

    private Face2FaceHelper face2FaceHelper;

    private FacePointsDetection facePointsDetection;

    private boolean inited=false;

//    File sdcard = Environment.getExternalStorageDirectory();

    String modelDir = "";

    static {

//        System.loadLibrary("caffe");
//        System.loadLibrary("caffe_jni");
        System.loadLibrary("facedetector_jni");
//        System.loadLibrary("face2face_jni");
//        System.loadLibrary("facepoints_jni");

    }

    @Override
    public void onCreate() {
        super.onCreate();
        Log.i(TAG, "Create");

//        MobclickAgent.setScenarioType(getApplicationContext(), MobclickAgent.EScenarioType.E_UM_NORMAL);
    }

    /**
     * 加载模型文件
     * @return
     */
    public void loadWisMobile() {

        TelephonyManager   telephonyManager  =  (TelephonyManager
                )getSystemService( Context.TELEPHONY_SERVICE );

            /*
	 * getDeviceId() function Returns the unique device ID.
	 * for example,the IMEI for GSM and the MEID or ESN for CDMA phones.
	 */
//        String imeistring = telephonyManager.getDeviceId();

//        String imsistring2 = telephonyManager.getSubscriberId();


        Log.i("WisApplication", "loadWisMobile");
        faceDetection = FaceDetection.getInstance();
        wisMobile = FaceMobile.getInstance();
        facePointsDetection=FacePointsDetection.getInstance();





        //设置模型文件路径
        modelDir = Environment.getExternalStorageDirectory().getPath() + "/facesdk";
        faceDetection.init(modelDir);
        File modelFile = new File(modelDir);
        if (!modelFile.exists()) {
            modelFile.mkdir();
        }
        String s2 = wisMobile.getSerialNo();
//        String s1 = wisMobile.getSerialNov2(1);
//        String s = faceDetection.getSerialNo(modelDir);
//        String s = faceDetection.getSerialNo();
//        String s3 = faceDetection.getSerialNov2(1);
        //将模型文件从资源文件中复制到
        initCopyFiles(modelDir);

        //判断是否加载模型，
//        if (!faceDetection.getInited() || !wisMobile.getInited() || facePointsDetection.getInited())
        if (!faceDetection.getInited() || !wisMobile.getInited())
        {
//            facePointsDetection.init(modelDir);
            faceDetection.init(modelDir);
            wisMobile.init(modelDir);

//            facePointsDetection.init(modelDir);
            //没有加载这加载，加载算法模型,成功后算法才能正常工作
            if (faceDetection.getInited() && wisMobile.getInited())
//            if (faceDetection.getInited() && wisMobile.getInited() && facePointsDetection.getInited())
            {
                wisMobile.setNumThreads(2);
                face2FaceHelper = Face2FaceHelper.getInstance();
                inited=true;
            }
        }




//        FaceModel faceModel[]=faceDetection.detectFace(rgbData, bmp.getWidth(), bmp.getHeight(), bmp.getWidth() * 3);
//        int faceRect[] = {faceModel[0].rtFace.x, faceModel[0].rtFace.y, faceModel[0].rtFace.width,
//                faceModel[0].rtFace.height};
//        float[] f=wisMobile.extractFeature(rgbData, bmp.getWidth(), bmp.getHeight(), bmp.getWidth() * 3,faceRect,faceModel[0].roll);
//        String strBase64="";
//        for (int i=0;i<f.length;i++)
//        {
//            strBase64+=Float.toString(f[i])+",";
//        }
//
//
//        try {
//            FileWriter fw = new FileWriter(modelDir + "/feature.txt");//SD卡中的路径
//            fw.flush();
//            fw.write(strBase64);
//            fw.close();
//        } catch (Exception e) {
//            e.printStackTrace();
//        }

    }

    private void initCopyFiles(String path) {
        try {
            Log.i("wisface", "start copy files----------> ");


            copyBigDataToSD(path + "/", "fdm1b.bin", "", "");
            copyBigDataToSD(path + "/", "fdm2b.bin", "", "");
            copyBigDataToSD(path + "/", "fdm1bin", ".mp3", "");
            copyBigDataToSD(path + "/", "fdm2bin", ".mp3", "");
            copyBigDataToSD(path + "/", "model.xml.gz", ".mp3", "");

            copyBigDataToSD(path + "/", "file2-model", ".mp3", "");
            copyBigDataToSD(path + "/", "file3-model", "", "");

            copyBigDataToSD(path + "/", "deta.param", "", "");
            copyBigDataToSD(path + "/", "detb.param", "", "");
            copyBigDataToSD(path + "/", "detc.param", "", "");

            copyBigDataToSD(path + "/", "deta.bin", "", "");
            copyBigDataToSD(path + "/", "detb.bin", "", "");
            copyBigDataToSD(path + "/", "detc.bin", "", "");

            copyBigDataToSD(path + "/", "model.2", "", "");

            copyBigDataToSD(path + "/", "model.3", "", "");
            copyBigDataToSD(path + "/", "model.4", "", "");

            copyBigDataToSD(path + "/", "landmarks.dat", ".mp3", "");

//            copyBigDataToSD("DCBCDE78B113C4C0571216404466252F2DB8D598.license");
            Log.i("wisface", "end start copy files----------> ");
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    private void copyBigDataBase() throws IOException {
        InputStream myInput;
        String outFileName = "/sdcard/wis/model_small.xml.mp3";
        Log.i("wisface", "start copy file " + outFileName);
        File f = new File(outFileName);
        if (f.exists()) {
            Log.i("wisface", "file exists " + outFileName);
            return;
        }
        OutputStream myOutput = new FileOutputStream(outFileName);
        for (int i = ASSETS_SUFFIX_BEGIN; i < ASSETS_SUFFIX_END + 1; i++) {
            String filename = "wis_alignment_0" + i;
            Log.i("wisface", "start copy files--- " + filename);
            myInput = this.getAssets().open(filename);

            byte[] buffer = new byte[1024];
            int length;
            while ((length = myInput.read(buffer)) > 0) {
                myOutput.write(buffer, 0, length);
            }
            myOutput.flush();
            myInput.close();
        }
        myOutput.close();
        Log.i("wisface", "end copy file " + outFileName);
    }


    private void copyBigDataToSD(String path, String strOutFileName, String sourceTag, String targetTag) throws IOException {
        Log.i("wisface", "start copy file " + strOutFileName);
        String tmpFile = path + strOutFileName + targetTag;
        File f = new File(tmpFile);
        if (f.exists()) {
            Log.i("wisface", "file exists " + strOutFileName);
            return;
        }
        InputStream myInput;
        OutputStream myOutput = new FileOutputStream(tmpFile);
        myInput = this.getAssets().open(strOutFileName + sourceTag);
        byte[] buffer = new byte[1024];
        int length = myInput.read(buffer);
        while (length > 0) {
            myOutput.write(buffer, 0, length);
            length = myInput.read(buffer);
        }
        myOutput.flush();
        myInput.close();
        myOutput.close();
        Log.i("wisface", "end copy file " + strOutFileName);
    }


    /**
     * 获取安卓设备机器码，用于后期授权生成license
     * @return
     */
    public String getSerialNo()
    {
        //判断是否加载算法模型文件
        if ((!inited))
        {
            loadWisMobile();
        }
//        return wisMobile.getSerialNov2(2);
        return wisMobile.getSerialNo();
    }

    /**
     * 人脸检测
     * @param bmp 检测图片Bitmap
     * @return 人脸模型,null为未检测到人脸
     */
    public FaceModel[] detectFaces(Bitmap bmp) {
        //判断是否加载算法模型文件
        if ((!inited))
        {
            loadWisMobile();
        }
        FaceModel[] models = null;
        if (bmp!=null)
        {
            try {
                long startTime = System.currentTimeMillis();
                models = faceDetection.detectFaceModel(bmp);
                long consumingTime = System.currentTimeMillis() - startTime;
                Log.i("hautmz", "detectFaceModel =" + consumingTime);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return models;
    }

    /**
     * 提取人脸特征码
     * @param bmp 图片
     * @param faceModel 图片中人脸的特征点模型，通过FaceDetection中人脸检测方法获取
     * @return 人脸特征码 成功为float[]数字，失败返回null
     * @throws Exception
     */
    public float[] extractFeature(Bitmap bmp,FaceModel faceModel)
    {
        //判断是否加载算法模型文件
        if ((!inited))
        {
            loadWisMobile();
        }
        float[] features=null;
        if (bmp!=null&&faceModel!=null)
        {
            try {
                long startTime = System.currentTimeMillis();
                features = wisMobile.getFaceFeature(bmp,faceModel);
                long consumingTime = System.currentTimeMillis() - startTime;
                Log.i("hautmz", "extractFeature =" + consumingTime);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return features;
    }

    /**
     * 获取2张人脸的相似度，适合1：N的场景，建议设置阈值为0.5
     * @param fea1 第一个人脸的特征码
     * @param fea2 第二个人脸的特征码
     * @return 2张人脸的相似度，
     */
    public float face2Face(float[] fea1,float[] fea2)
    {
        //判断是否加载算法模型文件
        if ((!inited))
        {
            loadWisMobile();
        }
        float score=-100;
        if (fea1!=null&&fea2!=null)
        {
            score=face2FaceHelper.face2Face(fea1,fea2);
        }
        return score;
    }

    /**
     * 获取2张人脸的相似度，适合1：1的场景，建议设置阈值为0.9
     * @param fea1 第一个人脸的特征码
     * @param fea2 第二个人脸的特征码
     * @return 2张人脸的相似度，
     */
    public float face2FaceV2(float[] fea1,float[] fea2)
    {
        //判断是否加载算法模型文件
        if ((!inited))
        {
            loadWisMobile();
        }
        float score=-100;
        if (fea1!=null&&fea2!=null)
        {
            score=face2FaceHelper.face2FaceV2(fea1,fea2);
        }
        return score;
    }

    /**
     * 设置提取特征值工作线程数
     * @param numThreads 线程数
     */
    public void setNumThreads(int numThreads)
    {
        wisMobile.setNumThreads(numThreads);
    }

    public FaceFeaturePoint[] detectedFacePoints(Bitmap bmp,FaceModel faceModel)
    {
        FaceFeaturePoint[] points=null;
        //判断是否加载算法模型文件
        if ((!inited))
        {
            loadWisMobile();
        }
        points = facePointsDetection.detectFacePoints(bmp,bmp.getWidth(),bmp.getHeight(),faceModel);
        return points;
    }

}
